﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Model;
using System.IO;
using Intorise.Common;
using System.Threading;
using Config;
using Intorise.API;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.Net.Sockets;
using System.Net;

namespace MuBot
{
    public partial class MainWindow : Form
    {
        List<Player> players = new List<Player>();
        /// <summary>
        /// 正在练级
        /// </summary>
        List<Player> running = new List<Player>();
        /// <summary>
        /// 等待练级
        /// </summary>
        List<Player> waiting = new List<Player>();
        List<FightLocation> fightLocation = null;
        System.Windows.Forms.Timer timer = null;
        BotConfig config;
        MainConfig mainConfig;
        ConfigWindow configWindow = null;
        Thread checkStatusThread = null;
        DateTime startTime = DateTime.MinValue;
        System.Threading.Timer rebootTimer = null;
        //ValidateCodeHelper validateCodeHelper = null;

        public MainWindow(params string[] args)
        {
            InitializeComponent();
            config = (BotConfig)ConfigManager.BusinessConfig;
            mainConfig = (MainConfig)ConfigManager.ApplicationConfig;
            configWindow = new ConfigWindow();

            if (args != null && args.Length > 0 && args[0].ToLower() == "/a")
            {
                if (args[0].ToLower() == "/a")
                {
                    Thread.Sleep(3000);
                    ConsoleBLL.WriteLineInfo("自动运行模式启动");
                    Init();
                    button2_Click(null, null);
                    btnStartAll_Click(null, null);
                }
            }

            ConsoleBLL.WriteLineInfo("程序将在" + mainConfig.RebootMinute + " 分钟后重启");
            rebootTimer = new System.Threading.Timer(new TimerCallback((x) =>
            {
                ConsoleBLL.WriteLineWaring("重新启动程序...");
                Process p = new Process();
                p.StartInfo = new ProcessStartInfo(Application.ExecutablePath);
                p.StartInfo.WorkingDirectory = Application.StartupPath;
                p.StartInfo.Arguments = "/a ";
                p.Start();
                Application.Exit();
            }), null, mainConfig.RebootMinute * 60 * 1000, mainConfig.RebootMinute * 60 * 1000);
        }

        public void Init()
        {
            //ConsoleBLL.Enabled = false;
            ConsoleBLL.AddDatetime = true;
            ConsoleBLL.Log = new Loger(AppDomain.CurrentDomain.BaseDirectory + "\\log.txt");
            ThreadPool.SetMaxThreads(1000, 1000);
            timer = new System.Windows.Forms.Timer();
            timer.Interval = config.RefreshInteravl * 1000;
            timer.Tick += new EventHandler(timer_Tick);
            fightLocation = FightLocation.Load();
            Player.BotFightLocations = BotFightLocation.Load();
            //validateCodeHelper = new ValidateCodeHelper(AppDomain.CurrentDomain.BaseDirectory + "\\37code.cds", "zheshijie101");
            //validateCodeHelper = new ValidateCodeHelper(AppDomain.CurrentDomain.BaseDirectory + "37code01.cds", "zheshijie101");
            //Bitmap img = (Bitmap)Bitmap.FromFile("e:\\1.png");
            //var data = File.ReadAllBytes("e:\\1.png");

            //MemoryStream stream = new MemoryStream();
            //img.Save(stream, ImageFormat.Jpeg);
            //data = stream.ToArray();
            //string code = validateCodeHelper.GetVcode(data);
            //MessageBox.Show("验证码：" + code);
            //ConsoleBLL.Enabled = false;
            this.Text = AppDomain.CurrentDomain.BaseDirectory;

            //InitRemoteControl();

        }

        void timer_Tick(object sender, EventArgs e)
        {
            this.dataGridView1.Refresh();
            var time = DateTime.Now - startTime;
            this.labMessage.Text = "已经用时：" + string.Format("{0}天{1}小时{2}分钟", time.Days, time.Hours, time.Minutes);
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            Init();
        }

        private void 加载账户ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult result;
            string[] fileNames = sender as string[];
            if (fileNames != null)
            {
                result = DialogResult.OK;
            }
            else
            {
                result = this.openFileDialog1.ShowDialog();
                fileNames = this.openFileDialog1.FileNames;
            }

            if (result != DialogResult.OK)
            {
                return;
            }

            //players.Clear();
            for (int i = 0; i < fileNames.Length; i++)
            {
                try
                {
                    FillAccounts(fileNames[i], players, false);
                }
                catch (Exception ex)
                {
                    if (MessageBox.Show("加载账户文件" + fileNames[i] + "时出错，您需要在重新加载这个文件吗？", "加载账户出错", MessageBoxButtons.OKCancel, MessageBoxIcon.Error) == DialogResult.OK)
                    {
                        i--;
                    }
                    ConsoleBLL.WriteLineWaring(ex.Message);
                    ConsoleBLL.WriteLineWaring(ex.StackTrace);
                }
            }

            ConsoleBLL.WriteLineWaring("已加载" + players.Count + "个账户");

            this.playerBindingSource.DataSource = null;
            this.playerBindingSource.DataSource = players;
        }

        public void WriterLineText(string text)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<string>(x =>
                {
                    this.labMessage.Text = x;
                }), text);
            }
            else
            {
                this.labMessage.Text = text;
            }
        }

        void FillAccounts(string filename, List<Player> list, bool clear)
        {
            if (clear)
            {
                list.Clear();
            }

            StreamReader sr = null;
            try
            {
                sr = new StreamReader(filename, Encoding.Default);
            }
            catch
            {
                throw;
            }
            try
            {
                while (!sr.EndOfStream)
                {
                    string[] items = sr.ReadLine().Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);
                    if ((items.Length > 4))
                    {
                        if (items[0] == "#") { continue; }
                        Account account = new Account();
                        account.Username = items[0];
                        account.Password = items[1];
                        account.ServerID = items[2];
                        if (SaveCompleteHelper.Finished(account.Username, account.ServerID))//已完成的账号
                        {
                            ConsoleBLL.WriteLine("跳过已完成账号：" + account.Username + "\t" + account.ServerID);
                            continue;
                        }
                        var player = new Player(account, config,"tw");

                        if (items.Length > 5)
                        {
                            int line = 0;
                            if (int.TryParse(items[5], out line))
                            {
                                player.Line = line;
                                player.SetLine = line;
                            }
                        }
                        if (items.Length > 6)
                        {
                            long masterid = 0;
                            if (long.TryParse(items[6], out masterid))
                            {
                                player.Master = new Warehouse { ID = masterid, Location = new Point(410, 132), Line = 1, CurrentMap = Maps.GetMap("地下城二层") };//仓库号的编号和停放地图地址
                            }
                        }
                        list.Add(player);
                    }
                }
                sr.Close();
            }
            catch
            {
                if (sr != null)
                {
                    sr.Close();
                }
                throw;
            }
        }

        private void btnStartAll_Click(object sender, EventArgs e)
        {
            this.btnStartAll.Enabled = false;
            startTime = DateTime.Now;
            timer.Enabled = true;
            waiting.Clear();
            waiting.AddRange(players);
            int count = 0;
            int max = 1000;//最多1000个
            for (var i = 0; i < waiting.Count && i < max; i++)
            {
                running.Add(waiting[i]);
                count++;
            }
            if (count > 0)
            {
                waiting.RemoveRange(0, count);
            }

            #region 运行账户
            GameHelper.RunThread(() =>
            {
                foreach (Player x in running)
                {
                    if (x.Status == PlayerStatusEnum.等待 || x.Status == PlayerStatusEnum.停止)
                    {
                        x.Quit();
                        Thread.Sleep(2000);
                        while (x.LoginCount < x.Config.MaxLoginCount)
                        {
                            if (x.Login())
                            {
                                x.AutoFight = true;
                                GameHelper.RunThread(x.Play);
                                break;
                            }
                        }
                    }
                }
                StartCheckStatus();

                while (waiting.Count > 0 || running.Count > 0)
                {
                    lock (running)
                    {
                        for (var i = 0; i < running.Count; i++)
                        {
                            if (running[i].Status == PlayerStatusEnum.任务完成 || running[i].Status == PlayerStatusEnum.停止)
                            {
                                running.RemoveAt(i);
                                i--;
                                if (waiting.Count > 0)
                                {
                                    running.Add(waiting[0]);
                                    waiting.RemoveAt(0);
                                }
                            }
                        }
                    }
                    Thread.Sleep(3000);
                }
                StopCheckStatus();
                this.btnStartAll.Enabled = true;
            });
            #endregion


        }

        private void btnStopAll_Click(object sender, EventArgs e)
        {
            if (this.btnStopAll.Text == "暂停打怪")
            {
                this.btnStopAll.Text = "继续打怪";
                players.ForEach(x =>
                {
                    x.Pause();
                });
            }
            else
            {
                this.btnStopAll.Text = "暂停打怪";
                players.ForEach(x =>
                {
                    x.Continue();
                });
            }

        }

        private void btnQuitAll_Click(object sender, EventArgs e)
        {
            //timer.Enabled = false;
            StopCheckStatus();
            players.ForEach(x =>
            {
                x.Quit();
            });
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            players.ForEach(x =>
            {
                x.Quit();
            });
            this.Close();
        }

        private void 配置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            configWindow.ShowDialog();
            timer.Interval = config.RefreshInteravl * 1000;
            players.ForEach(x => { x.RefreshConfig(); });
        }

        private void CheckStatus(object obj)
        {
            ConsoleBLL.WriteLineInfo("待运行账号状态检测已开始");
            while (true)
            {
                lock (running)
                {
                    var waitingPlayer = running.FirstOrDefault(x => x.Status == PlayerStatusEnum.等待 || x.Status == PlayerStatusEnum.已断线);
                    if (waitingPlayer != null)
                    {
                        waitingPlayer.Quit();
                        if (waitingPlayer.Login())
                        {
                            waitingPlayer.AutoFight = true;
                            GameHelper.RunThread((p) =>
                            {
                                Player player = (Player)p;
                                player.AutoFight = true;
                                player.Play();
                            }, waitingPlayer);
                        }
                        Thread.Sleep(config.LoginInteravl * 1000);
                    }
                }
                Thread.Sleep(config.CheckStatusInteravl * 1000);
            }
        }

        private void StartCheckStatus()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(x =>
            {
                StopCheckStatus();
                checkStatusThread = new Thread(new ParameterizedThreadStart(CheckStatus));
                checkStatusThread.IsBackground = true;
                checkStatusThread.Start();
            }));
            thread.Start();
        }

        private void StopCheckStatus()
        {
            if (checkStatusThread != null && checkStatusThread.ThreadState == System.Threading.ThreadState.Running)
            {
                while (checkStatusThread.ThreadState != System.Threading.ThreadState.Aborted && checkStatusThread.ThreadState != System.Threading.ThreadState.Stopped)
                {
                    try
                    {
                        checkStatusThread.Abort();
                    }
                    catch { }
                    Thread.Sleep(100);
                }
                ConsoleBLL.WriteLineInfo("待运行账号状态检测已停止");
            }
        }

        private void 重新开始ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in this.dataGridView1.SelectedRows)
            {
                Player player = ((Player)row.DataBoundItem);
                player.Quit();
            }
        }

        private void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
        {
            System.Environment.Exit(0);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string fileNames = "";
            fileNames = System.AppDomain.CurrentDomain.BaseDirectory + "账号.txt";

            try
            {
                FillAccounts(fileNames, players, false);
            }
            catch (Exception ex)
            {
                if (MessageBox.Show("加载账户文件" + fileNames + "时出错，您需要在重新加载这个文件吗？", "加载账户出错", MessageBoxButtons.OKCancel, MessageBoxIcon.Error) == DialogResult.OK)
                {
                    // i--;
                }
                ConsoleBLL.WriteLineWaring(ex.Message);
                ConsoleBLL.WriteLineWaring(ex.StackTrace);
            }

            ConsoleBLL.WriteLineWaring("已加载" + players.Count + "个账户");

            this.playerBindingSource.DataSource = null;
            this.playerBindingSource.DataSource = players;
        }

        private void dgvGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Rectangle rectangle = new Rectangle(e.RowBounds.Location.X,
                                                e.RowBounds.Location.Y,
                                                this.dataGridView1.RowHeadersWidth - 4,
                                                e.RowBounds.Height);

            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
                                    this.dataGridView1.RowHeadersDefaultCellStyle.Font,
                                    rectangle,
                                    this.dataGridView1.RowHeadersDefaultCellStyle.ForeColor,
                                    TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }
    }
}
